/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.yunhoo.pay.bean;

import com.ibatis.dao.client.DaoManager;
import com.yunhoo.asset.util.PayCodeConstants;
import com.yunhoo.base.bean.FinancialProjectBean;
import com.yunhoo.base.db.dao.DepartmentDao;
import com.yunhoo.base.db.dao.FinancialProjectDao;
import com.yunhoo.base.db.impl.PersonImpl;
import com.yunhoo.base.model.Department;
import com.yunhoo.base.model.FinancialProject;
import com.yunhoo.base.model.PayStyle;
import com.yunhoo.base.model.Person;
import com.yunhoo.pay.db.impl.AbroadGroupImpl;
import com.yunhoo.pay.db.impl.CommonOperationImpl;
import com.yunhoo.pay.db.impl.CostProofImpl;
import com.yunhoo.pay.model.Expense;
import com.yunhoo.pay.model.QueryVouchers;
import com.yunhoo.pay.util.BillOrder;
import com.yunhoo.pay.util.BillQueryToolKit;
import com.yunhoo.sys.util.common.LoginParam;
import com.yunhoo.sys.util.common.NavigationTool;
import com.yunhoo.sys.util.common.Null;
import com.yunhoo.sys.util.common.ToolKit;
import com.yunhoo.pay.util.ToolsMethed;
import com.yunhoo.sys.db.config.DaoConfig;
import com.yunhoo.sys.util.tree.TreeUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFooter;
import org.apache.poi.hssf.usermodel.HSSFHeader;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.richfaces.component.UIDataTable;
import org.richfaces.event.TreeSelectionChangeEvent;

/**
 *
 * @author Administrator
 */
@ManagedBean(name = "proofPay")
@SessionScoped
public class CostProofPayBean {

    private Expense voucher = new Expense();
    private LinkedList<Expense> proofList = new LinkedList<Expense>();
    private DataModel model = new ListDataModel();
    private List<Expense> billList = new ArrayList<Expense>();
    private DataModel billModel = new ListDataModel();
    private QueryVouchers qea = new QueryVouchers();//单据列表查询页面对象
    private String payWay;
    private String payWayType;
    private List<SelectItem> payStyleList;
    private UIDataTable data = null;
    private static DaoManager daom;
    private static DepartmentDao dao;
    private static FinancialProjectDao finProjdao;
    private DataModel<FinancialProject> finProjModel = null;
    private String status = "";

    public CostProofPayBean() {
        daom = DaoConfig.getDaoManager();
        dao = (DepartmentDao) daom.getDao(DepartmentDao.class);
        finProjdao = (FinancialProjectDao) daom.getDao(FinancialProjectDao.class);
        //buildDataTable();
        initbuildDataTable();
        initPayStyleList();
        initFinProjList();
    }

    private void initFinProjList() {
        if (finProjModel == null) {
            finProjModel = new ListDataModel<FinancialProject>();
        }
        try {
            List<FinancialProject> finli = finProjdao.queryAll(new FinancialProject(true));
            finProjModel.setWrappedData(finli);
        } catch (SQLException ex) {
            Logger.getLogger(FinancialProjectBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public final void initbuildDataTable() {
        Map map = new HashMap();
        map.put("cpsn_number", "");
        map.put("orgCode", curOrgCode().trim());
        map.put("voustatus", "'0','2','3','4','6'");
        billList = CostProofImpl.proofListPay(map);
        //billModel.setWrappedData(billList);
        if (proofList != null && proofList.size() > 0) {
            proofList.clear();
        }
        proofList.addAll(billList);
    }

    public void showVoucher() {
        voucher = (Expense) billModel.getRowData();
        //System.out.println("number: " + voucher.getNumber());
        setDefault();
        NavigationTool.getSelectedUrl("/page/pay/payment/operation/costProofForPay.xhtml");
    }

    //支付方式选择列表
    public final void initPayStyleList() {
        List<PayStyle> Styleli = AbroadGroupImpl.getPaystyleli();
        payStyleList = new ArrayList();
        for (PayStyle d : Styleli) {
            payStyleList.add(new SelectItem(d.getCode(), d.getName()));
        }
    }

    public void payWayChange(ValueChangeEvent event) {
        //System.out.println("payWayChange~~~");
        String code = (String) event.getNewValue();
        voucher.getPayStyle().setCode(code);
        List<PayStyle> li = AbroadGroupImpl.getPaystyleli();
        if (!Null.check(li) && !Null.check(code)) {
            for (PayStyle l : li) {
                if (code.trim().equals(l.getCode().trim())) {
                    voucher.setPayStyle(l);
                    payWayType = l.getType().trim();
                    //System.out.println("payWayType : " + payWayType);
                }
            }
        }
    }

    public void changeCashPaid() {
        if (!Null.check(voucher.getPayStyle().getType())) {
            if (voucher.getPayStyle().getType().equals("0")) {
                voucher.setCashPaid("1");
            } else {
                voucher.setCashPaid("0");
            }
        }
    }
    //支付检查

    public void checkPayandRep() {
        String payStatus = voucher.getNumberStatus();
        voucher.setNumberStatus("2");//防止填写“支付完毕”后单据未成功确认支付
        if (Null.check(voucher.getPayStyle().getCode())) {
            ToolKit.msgs_err("请选择支付方式");
        } else if (voucher.getPayaccount() == null) {
            ToolKit.msgs_err("请输入支付金额");
        } else if (voucher.getPayDate() == null) {
            ToolKit.msgs_err("请选择支付日期");
        } else if ("0".equals(voucher.getCashPaid()) && Null.check(voucher.getReceive())) {
            ToolKit.msgs_err("收款人不能为空!");
        } else if (voucher.getCashPaid() == null) {
            ToolKit.msgs_err("是否现金付讫！");
        } else if (Null.check(payStatus)) {
            ToolKit.msgs_err("是否支付完毕！");
        } else if ("1".equals(voucher.getCashPaid()) && voucher.getTicketcode().length() != 0) {
            ToolKit.msgs_err("现金付讫不需填写支付凭证号");
        } else if ("0".equals(voucher.getCashPaid()) && Null.check(voucher.getTicketcode())) {
            ToolKit.msgs_err("请填写支付凭证号");
        } else {
            if ("0".equals(voucher.getCashPaid())) {
                String str = voucher.getNumber() + voucher.getTicketcode();
                voucher.setTicketcode(str);
            }

            voucher.setNumberStatus(payStatus);
            pay();  //支付
            NavigationTool.getSelectedUrl("/page/pay/payment/table/queryCostProofForPay.xhtml");
        }
    }

    public void pay() {
        //voucher.setNumberStatus("4");
        voucher.setPayer(curPerNum().trim());
        Map map = new HashMap();
        map.put("voutype", voucher.getVoutype().trim());
        map.put("number", voucher.getNumber());
        map.put("numstatus", voucher.getNumberStatus());
        map.put("payaccount", voucher.getPayaccount());
        map.put("paystyle", voucher.getPayStyle().getCode());
        map.put("ticketcode", voucher.getTicketcode());
        map.put("payer", voucher.getPayer());
        map.put("paydate", voucher.getPayDate());
        map.put("cashPaid", voucher.getCashPaid());
        map.put("receive", voucher.getReceive());
        map.put("orgCode", curOrgCode().trim());
        CommonOperationImpl.updateVoucherForPay(map);
        queryExpenseAccount();
        //sendMail();
    }

    public void payRescind() {
        Map map = new HashMap();
        map.put("voutype", voucher.getVoutype().trim());
        map.put("number", voucher.getNumber().trim());
        map.put("orgCode", curOrgCode().trim());
        CommonOperationImpl.voucherRescindPay(map);
        refreshAfterOperation();
        NavigationTool.getSelectedUrl("/page/pay/payment/table/queryCostProofForPay.xhtml");
    }
    //选择预算项目

    public void selectProjForQuery() {
        FinancialProject fProj = finProjModel.getRowData();
        qea.getProject().setFinCode(fProj.getFinCode());
        qea.getProject().setFinName(fProj.getFinName());
    }
    //选择部门

    public void selecteDeptForQuery(TreeSelectionChangeEvent event) {
        Department dp = (Department) TreeUtil.listener(event);
        qea.getDept().setCode(dp.getCode());
        qea.getDept().setName(dp.getName());
    }

    public void queryExpenseAccount() {
        Map map = BillQueryToolKit.billQueryParamMap(qea);
        map.put("cpsn_number", "");
        map.put("orgCode", curOrgCode().trim());
        map.put("voustatus", "'2','4','6'");
        map.put("sql", Null.convert(status).trim());
        billList = CostProofImpl.proofListPay(map);
        billModel.setWrappedData(billList);
    }

    public void queryCancel() {
        qea = new QueryVouchers();
        status = "";
        Map map = new HashMap();
        map.put("orgCode", curOrgCode().trim());
        map.put("voustatus", "'0','2','3','4','6'");
        billList = CostProofImpl.proofListPay(map);
        billModel.setWrappedData(billList);
    }

    public void exportExcel() {
        HSSFWorkbook demoWorkBook = new HSSFWorkbook();
        HSSFSheet demoSheet = demoWorkBook.createSheet("支出证明单列表");
        String[] excelColumns = initTabeleHeader();
        List<Expense> rows = billList;

        HSSFHeader header = demoSheet.getHeader();
        header.setCenter("支出证明单列表");
        HSSFRow headerRow = demoSheet.createRow(0);
        for (int i = 0; i < excelColumns.length; i++) {
            HSSFCell headerCell = headerRow.createCell((short) i);
            //headerCell.setEncoding(HSSFCell.ENCODING_UTF_16);
            headerCell.setCellValue(excelColumns[i]);
        }
        //填充数据
        int rowIndex = 1;
        for (Expense row : rows) {
            createTableRow(demoWorkBook, demoSheet, row, rowIndex);
            rowIndex++;
        }
        TravelInputBean.exportExcel(demoWorkBook, demoSheet);

    }

    //初始化表头信息
    public String[] initTabeleHeader() {
        String[] excelColumns = {"单据编号", "单据状态", "单据日期", "报销内容", "报销金额", "预算项目", "经手人员", "部门", "支出类别", "预算来源", "经济分类", "支出渠道",
            "支付令", "核定金额", "还款金额", "待支付金额", "审核日期", "审核人", "支付金额", "支付日期", "出纳"};
        return excelColumns;
    }

    public static void createTableRow(HSSFWorkbook demoWorkBook, HSSFSheet demoSheet, Expense eit, int rowIndex) {
        //创建第rowIndex行
        CreationHelper createHelper = demoWorkBook.getCreationHelper();
        HSSFCellStyle dstyle = demoWorkBook.createCellStyle();
        dstyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-mm-dd"));//格式
        HSSFCellStyle dstyled = demoWorkBook.createCellStyle();
        dstyled.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0.00"));

        HSSFCell cell = null;
        HSSFRow row = demoSheet.createRow(rowIndex);

        cell = row.createCell(0);
        cell.setCellValue(PayCodeConstants.convertString(eit.getNumber()));
        cell = row.createCell(1);
        cell.setCellValue(PayCodeConstants.convertString(PayCodeConstants.functionNumberStatus().get(eit.getNumberStatus())));
        cell = row.createCell(2);
        cell.setCellValue(PayCodeConstants.convertDate(eit.getNumDate()));
        cell.setCellStyle(dstyle);
        cell = row.createCell(3);
        cell.setCellValue(PayCodeConstants.convertString(eit.getAffair()));
        cell = row.createCell(4);
        cell.setCellValue(PayCodeConstants.convertDouble(eit.getTotal()));
        cell.setCellStyle(dstyled);
        cell = row.createCell(5);
        cell.setCellValue(PayCodeConstants.convertString(eit.getProject().getFinName()));
        cell = row.createCell(6);
        cell.setCellValue(PayCodeConstants.convertString(eit.getUser().getCpsn_name()));
        cell = row.createCell(7);
        cell.setCellValue(PayCodeConstants.convertString(eit.getDept().getName()));
        cell = row.createCell(8);
        cell.setCellValue(PayCodeConstants.convertString(PayCodeConstants.formateCostClass().get(eit.getCostClass())));
        cell = row.createCell(9);
        cell.setCellValue(PayCodeConstants.convertString(eit.getBudgetSource()));
        cell = row.createCell(10);
        cell.setCellValue(PayCodeConstants.convertString(eit.getCostitem().getName()));
        cell = row.createCell(11);
        cell.setCellValue(PayCodeConstants.convertString(eit.getCostTypes().getName()));
        cell = row.createCell(12);
        cell.setCellValue(PayCodeConstants.convertString(eit.getPaycode()));
        cell = row.createCell(13);
        cell.setCellValue(PayCodeConstants.convertDouble(eit.getCheckaccount()));
        cell.setCellStyle(dstyled);
        cell = row.createCell(14);
        cell.setCellValue(PayCodeConstants.convertDouble(eit.getRepayment()));
        cell.setCellStyle(dstyled);
        cell = row.createCell(15);
        cell.setCellValue(PayCodeConstants.convertDouble(eit.getRemain()));
        cell.setCellStyle(dstyled);
        cell = row.createCell(16);
        if (eit.getAuditDate() == null) {
            cell.setCellValue("");
        } else {
            cell.setCellValue(PayCodeConstants.convertDate(eit.getAuditDate()));
            cell.setCellStyle(dstyle);
        }
        cell = row.createCell(17);
        cell.setCellValue(PayCodeConstants.convertString(eit.getAuditor()));
        cell = row.createCell(18);
        cell.setCellValue(PayCodeConstants.convertDouble(eit.getPayaccount()));
        cell.setCellStyle(dstyled);
        cell = row.createCell(19);
        if (eit.getPayDate() == null) {
            cell.setCellValue("");
        } else {
            cell.setCellValue(PayCodeConstants.convertDate(eit.getPayDate()));
            cell.setCellStyle(dstyle);
        }
        cell = row.createCell(20);
        cell.setCellValue(PayCodeConstants.convertString(eit.getPayer()));

    }

    public static void exportExcel(HSSFWorkbook demoWorkBook, HSSFSheet demoSheet) {
        try {
            String strfileName = "book.xls";
            FileOutputStream fos = null;
            //导出
            demoSheet.setGridsPrinted(true);//demoSheet
            HSSFFooter footer = demoSheet.getFooter();
            footer.setRight("Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages());
            // 获得JSF上下文环境
            FacesContext context = FacesContext.getCurrentInstance();
            // 获得ServletContext对象
            ServletContext servletContext = (ServletContext) context.getExternalContext().getContext();
            // 取得文件的绝对路径
            String excelName = servletContext.getRealPath("/upload") + "/" + strfileName;//strfileName
            File exportFile = new File(excelName);
            fos = new FileOutputStream(exportFile);//fos
            demoWorkBook.write(fos);//demoWorkBook
            fos.close();

            FacesContext ctx = FacesContext.getCurrentInstance();
            ctx.responseComplete();
            HttpServletResponse httpServletResponse = (HttpServletResponse) ctx.getExternalContext().getResponse();
            ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
            httpServletResponse.setHeader("Content-disposition", "attachment; filename=" + strfileName);//strfileName
            httpServletResponse.setContentLength((int) exportFile.length());//exportFile
            httpServletResponse.setContentType("application/x-download");
            //httpServletResponse.setContentType("application/vnd.ms-excel");
            byte[] b = new byte[1024];
            int i = 0;
            FileInputStream fis = new java.io.FileInputStream(exportFile);
            while ((i = fis.read(b)) > 0) {
                servletOutputStream.write(b, 0, i);
            }
            servletOutputStream.flush();
            ctx.responseComplete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void getFirst() {
        if (proofList.size() > 0) {
            voucher = proofList.getFirst();
            setDefault();
        } else {
            ToolKit.msgs_info("您尚未录入单据");
        }
    }

    public void previous() {
        int index = proofList.indexOf(voucher);
        if (index > 0) {
            this.setVoucher(proofList.get(index - 1));
            setDefault();
        } else {
            ToolKit.msgs_info("没有了");
        }
    }

    public void next() {
        int index = proofList.indexOf(voucher);
        if (index < proofList.size() - 1) {
            this.setVoucher(proofList.get(index + 1));
            setDefault();
        } else {
            ToolKit.msgs_info("没有了");
        }
    }

    public void getLast() {
        if (proofList.size() > 0) {
            voucher = proofList.getLast();
            setDefault();
        } else {
            ToolKit.msgs_info("您尚未录入单据");
        }
    }

    public void goback() {
        queryExpenseAccount();
        NavigationTool.getSelectedUrl("/page/pay/payment/table/queryCostProofForPay.xhtml");
    }

    public void toCata() {
        buildDataTable();
        NavigationTool.getSelectedUrl("/page/pay/payment/table/queryCostProofForPay.xhtml");
    }

    private void buildDataTable() {
        Map map = new HashMap();
        map.put("cpsn_number", "");
        map.put("orgCode", curOrgCode().trim());
        map.put("voustatus", "'2','4','6'");
        billList = CostProofImpl.proofListPay(map);
        billModel.setWrappedData(billList);
        if (proofList != null && proofList.size() > 0) {
            proofList.clear();
        }
        proofList.addAll(billList);
    }

    public void setDefault() {
        //System.out.println("payStyleCode: " + voucher.getPayStyle().getCode());
        if (voucher.getNumberStatus().trim().equalsIgnoreCase("2")) {
            voucher.setPayaccount(voucher.getTotal());
            voucher.setAuditDate(curLoginDate());
            if ("2".equals(voucher.getNumberStatus().trim()) && "P".equalsIgnoreCase(curPerRole().trim())) {
                voucher.setPayer(curPerName().trim());
                voucher.setReceive(voucher.getFeePer().getCpsn_name());
                voucher.setPayDate(new Date());
                payWay = "";
            } else {
                //System.out.println("payStyleCode: " + voucher.getPayStyle().getCode());
                payWay = voucher.getPayStyle().getCode();
            }
            forCashPaid();
        }
    }

    public void forCashPaid() {
        if (!Null.check(voucher.getPayStyle().getType()) && Null.check(voucher.getCashPaid())) {
            if (voucher.getPayStyle().getType().equals("0")) {
                voucher.setCashPaid("1");
            } else {
                voucher.setCashPaid("0");
            }
        }
    }

    public void sendMail() {
//        Person receiver = PersonImpl.queryByPerNumber(voucher.getUser().getCpsn_number().trim());
//        Person sender = PersonImpl.queryByPerNumber(curPerNum().trim());
//        ToolsMethed.sendMail(sender, receiver, "支付成功", "支付Done!!!");
    }

    public void refreshAfterOperation() {
        //voucher = CostProofImpl.proofByNumber(voucher.getNumber().trim());
        buildDataTable();
    }

    public void showFromPayView(Expense expense, DataModel viewModel) {
        voucher = expense;
        setDefault();
        billList = (List<Expense>) viewModel.getWrappedData();
        proofList = new LinkedList<Expense>();
        proofList.addAll(billList);
        NavigationTool.getSelectedUrl("/page/pay/payment/operation/costProofForPay.xhtml");
    }

    public List<Expense> getBillList() {
        return billList;
    }

    public void setBillList(List<Expense> billList) {
        this.billList = billList;
    }

    public DataModel<Expense> getBillModel() {
        return billModel;
    }

    public void setBillModel(DataModel billModel) {
        this.billModel = billModel;
    }

    public UIDataTable getData() {
        return data;
    }

    public void setData(UIDataTable data) {
        this.data = data;
    }

    public DataModel getModel() {
        return model;
    }

    public void setModel(DataModel model) {
        this.model = model;
    }

    public List<SelectItem> getPayStyleList() {
        return payStyleList;
    }

    public void setPayStyleList(List<SelectItem> payStyleList) {
        this.payStyleList = payStyleList;
    }

    public String getPayWay() {
        return payWay;
    }

    public void setPayWay(String payWay) {
        this.payWay = payWay;
    }

    public String getPayWayType() {
        return payWayType;
    }

    public void setPayWayType(String payWayType) {
        this.payWayType = payWayType;
    }

    public LinkedList<Expense> getProofList() {
        return proofList;
    }

    public void setProofList(LinkedList<Expense> proofList) {
        this.proofList = proofList;
    }

    public QueryVouchers getQea() {
        return qea;
    }

    public void setQea(QueryVouchers qea) {
        this.qea = qea;
    }

    public Expense getVoucher() {
        return voucher;
    }

    public void setVoucher(Expense voucher) {
        this.voucher = voucher;
    }
    //

    private String curPerNum() {
        return LoginParam.getPer().getCpsn_number();
    }

    private String curPerName() {
        return LoginParam.getPer().getCpsn_name();
    }

    private String curDeptCode() {
        return LoginParam.getDept().getCode();
    }

    private String curDeptName() {
        return LoginParam.getDept().getName();
    }

    private Date curLoginDate() {
        return LoginParam.getLoginDate();
    }

    private Integer curIyear() {
        return LoginParam.getIyear();
    }

    private String curOrgCode() {
        return LoginParam.getOrg().getCode();
    }

    private String curPerRole() {
        return LoginParam.getPer().getRole();
    }

    public List<SelectItem> getPayStatusList() {
        List<SelectItem> payStatusList = new ArrayList<SelectItem>();
        payStatusList.add(new SelectItem("0,2,3", "未支付"));
        payStatusList.add(new SelectItem("4,6", "已支付"));
        return payStatusList;
    }

    public DataModel<FinancialProject> getFinProjModel() {
        return finProjModel;
    }

    public void setFinProjModel(DataModel<FinancialProject> finProjModel) {
        this.finProjModel = finProjModel;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}
